<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta
      http-equiv="X-UA-Compatible"
      content="IE=edge"
    />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0"
    />
    <title>Document</title>
  </head>
  <body>
    <script>
      let isMount = true;
      let workInProgressHook = null; //指向当前执行的hook

      // 当前函数组件的fiber
      const fiber = {
        memoizedState: null,
        stateNode: App,
      };

      function run() {
        workInProgressHook = fiber.memoizedState;
        const app = fiber.stateNode();
        isMount = false;
        return app;
      }

      function dispatchAction(queue, action) {
        const update = {
          action,
          next: null,
        };

        if (queue.pending === null) {
          update.next = update;
        } else {
          update.next = queue.pending.next;
          queue.pending.next = update;
        }
        queue.pending = update;
        run();
      }

      function useState(initialState) {
        let hook;

        if (isMount) {
          hook = {
            queue: {
              pending: null,
            },
            memoizedState: initialState,
            next: null,
          };
          // 将 hooks 处理成单向链表
          if (!fiber.memoizedState) {
            fiber.memoizedState = hook;
          } else {
            workInProgressHook.next = hook;
          }
          // 指向当前 hook
          workInProgressHook = hook;
        } else {
          hook = workInProgressHook;
          workInProgressHook =
            workInProgressHook.next;
        }

        let baseState = hook.memoizedState;
        // 处理这个 hook 存在的 update
        if (hook.queue.pending) {
          let firstUpdate =
            hook.queue.pending.next;

          do {
            const action = firstUpdate.action; // 这里action 就是调用 hooks 函数时传递的参数，（这里简化版只处理函数）
            baseState = action(baseState);
            firstUpdate = firstUpdate.next;
          } while (
            firstUpdate !==
            hook.queue.pending.next
          );

          hook.queue.pending = null;
        }

        hook.memoizedState = baseState;

        return [
          baseState,
          dispatchAction.bind(null, hook.queue),
        ];
      }

      function App() {
        const [num, updateNum] = useState(0);

        console.log(num, "number");

        return {
          onClick() {
            updateNum(num => num + 1);
          },
        };
      }

      window.app = run();
    </script>
  </body>
</html>
